;======================================
;Galaxo Blast
;(Game Code)
;
;(C)2026 The New Dimension
;Written by Richard Bayliss
;
;For Fun and Games Programming in 
;Assembly - Part 3
;
;Memory locations used:
;----------------------
;
;     --- GAME BITS ---
;SPRITES      $2000-$2CFF
;GAME SCREEN  $3000-$33E7
;GAME COLOUR  $3400-$37E7
;CHARSET      $3800-$3EFF              
;GAME CODE    $3F00-$4FFF
;SFX PLAYER   $5000-$53FF
; --- TITLE SCREEN BITS ---
;MUSIC        $0D00-$1FFF
;TITLE CODE   $5400-$57ff
;LOGO COLRAM  $5800-$5be7
;LOGO VIDRAM  $5c00-$5de7
;LOGO BITMAP  $6000-$7000
;SCREEN TEXT  $7000-$7400
;SCREEN COL   $7400-$77E7
;SCROLLTEXT   $7800-$7FFF
;-------------------------------------
;Define labels/variables

;Start address for title code
titlecode = $5400
;--------------------------------------
;Screen data read / write addresses
scrn = $0400 ;VIC2 screen RAM (bank 3)
colr = $d800 ;VIC2 colour RAM
gamescrn = $3000 ;Game screen data 
gamecol = $3400  ;Game colour data
;Sprite boundary stop variables 
ustop = $32 
dstop = $ca 
lstop = $0c
rstop = $a0 

;Box collision boundary variables for 
;both player, enemies and bullets

boxu = $18
boxd = $0c
boxl = $06
boxr = $0c

;Status panel screen character
;posiition.

alienstxt = $0413
alienscol = $d813
scoretxt = $079f
scorecol = $db9f
livestxt = $07ac
livescol = $dbac
leveltxt = $07b4
levelcol = $dbb4
hitxt = $07b9
hicol = $dbb9
gotxt = $05c8
gocol = $d9c8

;EOR code for changing PETSCII text 
;to the correct characters before 
;pasting to screen.
eorcode = $40

;Sprite values
blanksprite = $af

;Star field character address position
;$0800 + (64*8)
fldchar1 = $3a00
;$0800 + (80*8)
fldchar2 = $3a80
;$0800 + (96*8)
fldchar3 = $3b00

;Sound effects 

; Player firing
sfxpfire = $00 
; Enemy firing
sfxefire = $01
; Enemy dead 
sfxedead = $02
; Player dead 
sfxpdead = $03
; Level complete
sfxlclear = $04
; Game Over 
sfxgover = $05
; Alien spawn sound
sfxespawn = $06
; Game complete 
sfxgfinish = $04
;Extra life 
sfxextralife = $07
;SFX parameters 
sfxinit = $5000
sfxplay = $5003

;Starfield backup address for copying
;the starfield before text writes over 
;it.

starbackup = $0900
;======================================
 *=$3f00 ;Declare start address
;====================================== 

;This sets up the 
;video standard (PAL or NTSC). This is
;used for the title screen music 
;player, and in game SFX player.
            
checksys
    lda $d012
    cmp $d012
    beq *-3
    bmi checksys
    cmp #$20 ;Check raster line
    bcc ntscfound

; The program has detected a PAL system
 
        lda #1
    sta system
        jmp exitcheck

; The program has detected an NTSC
; system.    

ntscfound
    lda #0
    sta system

;-------------------------------------  
;Kill existing IRQ raster interrupts 
;--------------------------------------

exitcheck    

; Disables RUN/STOP and RESTORE, if 
; using TURBO MACRO PRO for testing 
; on your C64. Comment the command and
; uncomment this below to allow access
; to your assembler. 

                 lda #251
         sta $0328

;Press RESTORE to jump back to Turbo
;Macro Pro V1.2+ assembler. 

;assembler = $0140 ;(if using REU)
;assembler = $8000 ;(not using REU)
;assembler = $9000 ;Turbo Assembler
                

     sei 
     ldx #$fb
     tsx
     ldx #$31 
     ldy #$ea 
     stx $0314
     sty $0315
     lda #$00
     sta $d019 
     sta $d01a 
     lda #$81
     sta $dc0d
     sta $dd0d
     lda $dc0d
     lda $dd0d 
     lda #$0b 
     sta $d011
     lda #11
     sta bgflashpointer
         
; Initialise SID chip

     ldx #$00
initsid 
     lda #$00
     sta $d400,x 
     inx 
     cpx #$18
     bne initsid 

;-------------------------------------  

; Setup the game graphics 

setupgame    
     lda #$18 ;Multi colour chars
     sta $d016 
     
     lda #$1e ;Charset
     sta $d018 
     
     lda #$0b  ;Charset
     sta $d022 ;Multicolour 1
     
     lda #$01  ;Charset 
     sta $d023 ;Multicolour 2
     
     lda #$00  ;Black border
     sta $d020 ;and 
     sta $d021 ;background

         lda #$03  ;VIC2 BANK $03
         sta $dd00
         
; Initialise all pointers 

     ldx #$00
clearptrs
    lda #0
    sta ptrstart,x
    inx
    cpx #ptrend-ptrstart
    bne clearptrs
         
; Draw game screen

     ldx #$00
drawscrn lda gamescrn,x 
     sta scrn,x 
     lda gamescrn+$100,x
     sta scrn+$100,x
     lda gamescrn+$200,x
     sta scrn+$200,x
     lda gamescrn+$2e8,x
     sta scrn+$2e8,x
     lda gamecol,x 
     sta colr,x
     lda gamecol+$100,x
     sta colr+$100,x
     lda gamecol+$200,x
     sta colr+$200,x
     lda gamecol+$2e8,x
     sta colr+$2e8,x
     inx 
     bne drawscrn 
     
; Paint the starfield according to the
; colour table values

     ldx #$00
     ldy #$00
paintstars 
     lda starcols,y
     sta colr,x 
     sta colr+$100,x
     sta colr+$200,x
     sta colr+$2e8,x 
     inx 
     beq paintdone
     iny
     cpy #7
     bne paintstars
     ldy #0
     jmp paintstars
paintdone     

;Restore the status panel colour data

     ldx #$00
restorepanelc
     lda gamecol+(22*40),x
     sta colr+(22*40),x
     inx
     cpx #$78
     bne restorepanelc
         
;Put chevrons on screen by counter 
;that should kill number of aliens 
;during play. 

        lda #$3e
        sta $040f
        sta $0410
        sta $0411
        lda #$3c
        sta $0417
        sta $0418
        sta $0419
     
; Setup VIC2 for sprites. Including,
; multi colour settings 

    lda #$00  ;All switched off 
    sta $d017 ;for expand sprite X
    sta $d01b ;sprite behind char
    sta $d01d ;expand sprite Y
    lda #$ff  ;All switched on 
    sta $d015 ;for sprites enabled
    sta $d01c ;sprite Multicolour
    lda #$0b  ;Sprite multicolour 1
    sta $d025 
    lda #$01  ;Sprite multicolour 2
    sta $d026 
   
; Reset the player's score and lives 

    ldx #$00
resetscore 

; Set score and virtual score as 000000
    lda #$30
    sta score,x 
        sta vscore,x
    inx
    cpx #$06
    bne resetscore 
; Set lives to 5    
    lda #$35
    sta lives 
; Set level to 1    
    lda #$31
    sta level 
;-------------------------------------  
;Setup IRQ raster interrupt player 
;--------------------------------------
    ldx #<gameirq
    ldy #>gameirq
    lda #$7f
    stx $0314
    sty $0315
    sta $dc0d 
    sta $dd0d 
    lda $dc0d
    lda $dd0d
    lda #$32 ;Set raster start
    sta $d012 ;position
    lda #$1b ;Restore screen
    sta $d011
    lda #$01 ;Acknowledge 
    sta $d01a ;interrupts

; Play enemy spawn sfx    
    lda #sfxespawn 
    jsr sfxinit    
    cli 
    jmp buildlevel
;-------------------------------------- 
;Main IRQ raster interrupt player 
;--------------------------------------
gameirq 
    inc $d019 
    lda #$fa
    sta $d012
    lda #1
    sta rt 
; Main SFX player   
    jsr sfxplayer
    jmp $ea7e
  
; PAL/NTSC based SFX player 

sfxplayer
    lda system
    cmp #1
    beq palsfx
    inc ntsctimer
    lda ntsctimer
    cmp #6
    beq resetntsc1
palsfx
    jsr sfxplay 
    rts
     
; Reset NTSC counter to zero so we 
; can loop the timer.

resetntsc1
    lda #0
    sta ntsctimer
    rts
;--------------------------------------
;Level start: Sets up the levels 
;for the game. (Simply copies and 
;pastes specific tables to correct 
;locations, according to the level 
;which the player is at).

buildlevel 
    ldx levelpointer 
    lda spawntblo,x 
    sta spawnsm+1
    lda spawntbhi,x 
    sta spawnsm+2
    lda firetbl,x
    sta fireduration
    
; also copy the shoot count values that
; are set in digits 

    lda digitset1,x 
    sta aliensleft
    lda digitset2,x
    sta aliensleft+1
    lda digitset3,x 
    sta aliensleft+2
    
; Setup level value and store to 
; to the level 

    lda levelnos,x 
    sta level
    
; Copy spawn generator sequence tables
; enemy spawn table. So that we can 
; have enemy spawn sequences according 
; to the level which the player is 
; based. 

    ldx #$00
spawnsm 
    lda l1spawntbl,x 
    sta spawntbl,x
    inx 
    cpx #45
    bne spawnsm
    
    ldx #0
    stx selectptr
    
;Default player starting position and 
;bullet starting position

    ldx #$00
dflt  lda startpos,x 
    sta objpos,x
    inx 
    cpx #4
    bne dflt    
    
; Setup the game sprites and position 
; Assign sprite start position and 
; store to the object position for The
; sprites 
levelstart

; Initialise the enemy spawn SFX 

    lda #sfxespawn
    jsr sfxinit
    
; Call subroutine to select next table
; to spawn enemy 

    jsr spawnnext
    
; Select properties for 
; --- ENEMY SPRITE 1 ---

; Grab enemy type selection 

    ldx selectptr2
    lda etypelo,x
    sta e1tsm+1
    lda etypehi,x 
    sta e1tsm+2

; Grab enemy colour selection 

    lda ecolour,x 
    sta e1csm+1

; Grab enemy speed 

    lda espeedx,x 
    sta startspeed
    lda espeedy,x 
    sta startspeed+1
        
; Grab hitpoints to kill enemy    

    lda ehits,x 
    sta hitpoints
    sta hitpoints+1
    
; Select properties for:
; --- ENEMY SPRITE 2 ---
; Grab enemy type selection   

    jsr spawnnext
    ldx selectptr2  
    lda etypelo,x
    sta e2tsm+1
    lda etypehi,x 
    sta e2tsm+2

; Grab enemy colour selection 

    lda ecolour,x 
    sta e2csm+1

; Grab enemy speed 

    lda espeedx,x 
    sta startspeed+2
    lda espeedy,x 
    sta startspeed+3

; Grab hitpoints to kill enemy    

    lda ehits,x 
    sta hitpoints+2
    sta hitpoints+3
    
; Select properties for         
; --- ENEMY SPRITE 3 ---
; Grab enemy type selection 

    jsr spawnnext
    ldx selectptr2
    lda etypelo,x
    sta e3tsm+1
    lda etypehi,x 
    sta e3tsm+2

; Grab enemy colour selection 

    lda ecolour,x 
    sta e3csm+1

; Grab enemy speed 

    lda espeedx,x 
    sta startspeed+4
    lda espeedy,x 
    sta startspeed+5

; Grab hitpoints to kill enemy    

    lda ehits,x 
    sta hitpoints+4
    sta hitpoints+5
    
; Select properties for         
; --- ENEMY SPRITE 4 ---
; Grab enemy type selection 

    jsr spawnnext
    ldx selectptr2 
    lda etypelo,x
    sta e4tsm+1
    lda etypehi,x 
    sta e4tsm+2

; Grab enemy colour selection 

    lda ecolour,x 
    sta e4csm+1

; Grab enemy speed 

    lda espeedx,x 
    sta startspeed+6
    lda espeedy,x 
    sta startspeed+7

; Grab hitpoints to kill enemy    

    lda ehits,x 
    sta hitpoints+6
    sta hitpoints+7
    
; Select properties for         
; --- ENEMY SPRITE 5 ---
; Grab enemy type selection 

    jsr spawnnext 
    ldx selectptr2
    lda etypelo,x
    sta e5tsm+1
    lda etypehi,x 
    sta e5tsm+2

; Grab enemy colour selection 

    lda ecolour,x 
    sta e5csm+1

; Grab enemy speed 

    lda espeedx,x 
    sta startspeed+8
    lda espeedy,x 
    sta startspeed+9

; Grab hitpoints to kill enemy    

    lda ehits,x 
    sta hitpoints+8
    sta hitpoints+9

; Disable background flash        

        ldx #11
        stx bgflashpointer
        
        
; Reset the shield pointer and player 
; shield in general 

        lda #200
        sta shieldtimer
        lda #0
        sta shieldptr
        
;All enemy bits have been setup, 
;start the spawn engine. Then play 
;the game.    

    jmp dospawn
    
;Subroutine Spawn next. Selects each 
;byte in the selection table to Spawn
;the next alien in sequence 

; Select the values of each table 
; according to the select pointer 
; set. (This should take place with 
; five different enemies.

spawnnext
    ldy selectptr
    lda spawntbl,y
    sta selectptr2    
    iny
    cpy #45
    beq rstspawn
    inc selectptr
    rts 
rstspawn 
    ldy #0
    sty selectptr
    rts
        
dospawn

;Select and modify the spawn position
;table then position everything

        ldx spawnposptr
        lda spawnseqtbl,x 
        sta spawnposptr+1
        inx 
        cpx #50
        beq wrapspwn
        inc spawnposptr 
        jmp spawnit

; The sequence pointer is reset

wrapspwn 
        ldx #$00
        stx spawnposptr
spawnit        
        ldx spawnposptr+1
        lda spawnposlo,x 
        sta spossm+1
        lda spawnposhi,x 
        sta spossm+2
        
        ldx #$00
spossm 
        lda spawnptbl1,x
        sta spawnpos,x
        inx 
        cpx #$0a
        bne spossm
        
    ldx #$00
blankbad
    lda #blanksprite
    sta $07fa,x 
    inx 
    cpx #$0a 
    bne blankbad
    ldx #$00
setstrt 
    lda spawnpos,x 
    sta enemypos,x
    inx 
    cpx #$0a ;10 bytes 5 enemies
    bne setstrt
   
; Reset the sprite animation frame and
; delay pointer 

    lda #$00
    sta animspeed
    sta animptr
    
;Copy the start speed of the enemy 
;movement 

    ldx #$00
copyspd 
    lda startspeed,x 
    sta enemyspeed,x 
    inx 
    cpx #$0a ;10 bytes 5 enemies
    bne copyspd 

; Paint all the game sprites     

    ldx #$00
pntspr  lda sprcolour,x 
    sta $d027,x 
    inx 
    cpx #8
    bne pntspr 
   
;Update the status panel once

    jsr updatepanel
    
; Now our first loop, this will morph
; all the aliens into the game, but 
; also keep the player moving.

morphloop 
; Synchronise timer (rt) with raster
    jsr synctimer

; Prevent aliens from shooting any
; more bullets whilst morphing into
; the screen 

	lda #0
	sta bullwaittime

; Make sprites move in full screen 
; area    

    jsr expandmsb 
; Animate the game starfield    

    jsr starfield

; Call subroutine that controls the 
; player ship.    

    jsr playerctrl

; Call subroutine that controls the
; player bullet.    

    jsr pbullctrl

; Also allow the enemy bullet to 
; continue falling
        
        jsr ebcontrol
        
; And enable collision detection 

        jsr coldetect
        
; Flash the enemy hit counter 

    jsr flashcounter

;The main alien morph animation routine

    lda animspeed
    cmp #4
    beq morphok
    inc animspeed
    jmp morphloop
morphok lda #0
    sta animspeed 
    ldx animptr
    ldy #$00
setsprmo
    lda morphframe,x 
    sta $07fa,y
    lda #$03
    sta $d029,y
    iny
    cpy #$05
    bne setsprmo
    inx 
    cpx #4
    beq gameloop
    inc animptr 
    jmp morphloop   
    
;-------------------------------------- 
;Main game loop 
;--------------------------------------
gameloop

; Synchronise timer
    jsr synctimer

; Expand sprite area        
    jsr expandmsb

; Animate starfield        
    jsr starfield

; Call main gameplay logic. 
    jsr gamelogic
    jmp gameloop
;--------------------------------------
  
;Synchronise game timer pointer with
;the IRQ raster interrupt   
;--------------------------------------
synctimer 
    lda #0
    sta rt
    cmp rt
    beq *-3
    jsr flashbg
        
;Check for game pause / abort function
;The game can be paused by pressing 
;CONTROL and aborted by pressing BACK 
;ARROW. The game can be resumed by 
;pressing fire in port 2.

;1. We check if CONTROL has been 
;pressed to pause the game.

        lda $dc01 
        lsr 
        lsr
        lsr
        bcs resumegame
		
;2. The game is paused, check if BACK 
;ARROW key has been pressed to abort 
;the game back to the title screen.
		
gamepaused 
        lda $dc01
        lsr
        lsr
        bcs checkunpause
        jmp abortgame
		
;3. The game is still paused, check if 
;the fire button has been pressed to 
;resume game play. 

checkunpause		
        lda $dc00
        lsr 
        lsr 
        lsr 
        lsr 
        lsr
        bcs gamepaused 
resumegame        
        rts
        
;Quit game, so jump back to the title 
;screen. 
        
abortgame        
        jmp $5400
    
;--------------------------------------
; Flashing background, this will 
; occur everytime a level has been 
; completed.
;--------------------------------------
flashbg 
    lda bgflashdelay
    cmp #1
    beq dobgflash
    inc bgflashdelay
    rts
dobgflash 
        lda #0
        sta bgflashdelay
    ldx bgflashpointer 
    lda bgflashtbl,x 
        sta $d021
    inx 
    cpx #12
    beq stopbgf
    inc bgflashpointer 
    rts 
stopbgf ldx #11
    stx bgflashpointer
    rts 
;--------------------------------------
;Set all sprite position pointers back
;as actual hardware sprite X/Y position
;Expand the horizontal position area 
;so that sprites can move across the 
;whole screen area. 
;--------------------------------------
expandmsb
    ldx #$00
exploop lda objpos+1,x
    sta $d001,x
    lda objpos,x 
    asl a
    ror $d010 ;MSB
    sta $d000,x ;Sprite X HW
    inx
    inx 
    cpx #16 ;X/Y all 8 sprites 
    bne exploop 
    rts 
;-------------------------------------  
;Generate starfield parallax effect
;-------------------------------------
starfield 
    jsr sffast
    jsr sfmedium
    jsr sfslow 
    rts 
    
;Fast scrolling star chars 
sffast
    lda fielddelay1
    ;cmp #1
    beq dostars1
    inc fielddelay1
    rts 
dostars1 
    lda #0
    sta fielddelay1
    lda fldchar1+$7f
    sta ftemp1 
    
; Roll 16 chars downwards to 
; make effect

    ldx #$7e
swrap1  lda fldchar1,x
    sta fldchar1+1,x 
    dex 
    bpl swrap1 
    
; Store backup to first char 
; in group 1

    lda ftemp1 
    sta fldchar1
    rts 
    
;Medium scrolling star chars 

sfmedium
    lda fielddelay2
    cmp #1
    beq dostars2
    inc fielddelay2
    rts 
dostars2 
    lda #0
    sta fielddelay2
    lda fldchar2+$7f
    sta ftemp2 
    
; Again roll 16 chars downwards

    ldx #$7e
swrap2  lda fldchar2,x
    sta fldchar2+1,x 
    dex 
    bpl swrap2 
    
; Store backup to first char in 
; group 2

    lda ftemp2 
    sta fldchar2
    rts 
    
;Slow scrolling starfield 

sfslow  lda fielddelay3
    cmp #2
    beq dostars3 
    inc fielddelay3
    rts   
dostars3 
    lda #0
    sta fielddelay3   
    lda fldchar3+$7f
    sta ftemp3    
    
; Once more roll 16 chars downwards  

    ldx #$7e
swrap3  lda fldchar3,x 
    sta fldchar3+1,x 
    dex 
    bpl swrap3
    
;Store backup to first char in 
;group 3. 

    lda ftemp3 
    sta fldchar3
    rts 
;--------------------------------------
;Loop for game logic 
;--------------------------------------
gamelogic 

; Sprite frame animation subroutine   
    jsr animsprs
        
; Player control subroutine   
    jsr playerctrl
        
; Bullet firing control
    jsr pbullctrl
        
; Enemy control
    jsr enemyctrl
        
; Enemy bullet control 
    jsr ebcontrol
        
; Collision registry
    jsr coldetect
        
; Check all enemies killed 
    jsr checkalldead
        
; Finally flash quota 
        jsr flashcounter
        
    rts
;--------------------------------------
; Animate those game sprites. All 
; sprites to use same animation speed
;--------------------------------------
animsprs 
    lda animspeed
    cmp #4
    beq animsprt
    inc animspeed
    rts 
animsprt
    lda #0
    sta animspeed
    ldx animptr
    lda playerframe,x 
    sta plrtype 
    lda enemyframe1,x 
    sta enemy1type
    lda enemyframe2,x 
    sta enemy2type
    lda enemyframe3,x
    sta enemy3type 
    lda enemyframe4,x 
    sta enemy4type 
    lda enemyframe5,x 
    sta enemy5type 
    lda enemyframe6,x 
    sta enemy6type
    lda enemyframe7,x 
    sta enemy7type
    lda enemyframe8,x 
    sta enemy8type
    inx 
    cpx #4
    beq loopanimsp
    inc animptr 
    rts 
loopanimsp 
    ldx #0
    stx animptr
    rts
;--------------------------------------
;Player control
;--------------------------------------
playerctrl    

; Check if th player is alive. If not 
; then morph it into an explosion.

    lda playerdead
    beq plractive
    jmp destroyplr
    
; The player is alive 

plractive
        jsr flashshield
    lda plrtype
    sta $07f8
        
; Check if the player shield is active
        
        lda shieldtimer
        beq noshield 
        dec shieldtimer 
        jmp maincontrol
        
; Shield is active so flash player 
        
flashshield 
        ldx shieldptr
        lda shieldcol,x
        sta $d027
        inx 
        cpx #$08
        beq loopshd
        inc shieldptr 
        jmp maincontrol
loopshd
        ldx #0
        stx shieldptr 
        jmp maincontrol
        
; Shield is not active so default 
; player's colour to cyan

noshield        
    lda #3
    sta $d027
        
; Read joystick port left 2

maincontrol
    lda #4 ;Read left 
    bit $dc00
    bne notleft

; Move player left 

    lda shippos
    sec 
    sbc #1 ;Slow ship 
    cmp #$0c ;Stop position left
    bcs storlft
    lda #$0c
storlft sta shippos

; Read joystick port 2 right

notleft   
    lda #8 ;Read right 
    bit $dc00
    bne notright
        
; Move player right     

    lda shippos 
    clc 
    adc #1 
    cmp #$a0 ;Stop position right 
    bcc storrgt
    lda #$a0
storrgt sta shippos

; Check for fire button

notright
    lda #16
    bit $dc00 
    bne noplay

; Is bullet already on screen?

    lda pbullpos ;Bullet pos X
    beq armplr ;Player ready 
    jmp noplay 

; Arm player with the bullet sprite 

armplr  lda shippos+1
    sta pbullpos+1
    lda shippos
    sta pbullpos
    lda #sfxpfire 
    jsr sfxinit
noplay  rts

; Player death animation 

destroyplr
    lda deathdelay
    cmp #2
    beq deathmain
    inc deathdelay
    rts 
    
deathmain 
    lda #0
    sta deathdelay
    ldx deathpointer
    lda explframe,x 
    sta $07f8 
    lda #$0e
    sta $d027
    inx 
    cpx #6
    beq stopdeath
    inc deathpointer
    rts 
stopdeath

; Subtract 1 life from the 
; lives counter, then update 
; the status panel.

    dec lives 
    lda lives
        
; if lives = 0 then game over   

    cmp #$30 
    beq gameover
        
; update status panel again 

    jsr updatepanel
        
; Reset player the shield again 

        lda #200
        sta shieldtimer
        ldx #0
        stx shieldptr
    lda #0
    sta playerdead
    rts
;--------------------------------------
  
; The game is over

gameover
    lda #0
        sta firebutton
        
; Play the game over Sound Effects 

    lda #sfxgover
    jsr sfxinit
    
; Switch off all the sprites 

    lda #0
    sta $d015
    
;Check if player gets hi score      

    jsr checkhi
        
; Then display the game over text 

    ldx #$00
copygotxt
    lda gomsg,x 
    sec
    sbc #eorcode
    sta gotxt,x 
    lda #2
    sta gocol,x 
    inx 
    cpx #9 ;Length of text
    bne copygotxt
    
; Main game over loop
gameoverloop

    jsr synctimer
    jsr starfield
        jsr flashcounter
        
        lda $dc00
        lsr
        lsr
        lsr
        lsr 
        lsr 
        bit firebutton
        ror firebutton
        bmi gameoverloop
        bvc gameoverloop 
        
    jmp titlecode
;--------------------------------------
; Player bullet control routine 
;-------------------------------------- 

pbullctrl

; Check if player bullet is dead 
; before deciding on which frame the 
; object should use.

    lda bulldead
    cmp #1
    bne pbullok
    jmp killbull
    
    
; No bullet killed, make sure the 
; bullet shows on sprite 1 and set its
; colour as yellow 

pbullok   

    lda pbullframe
    sta $07f9
    lda #$07
    sta $d028
    
    lda objpos+3
    sec
    sbc #8
    cmp #ustop
    bcs pbullstor
    lda #$00
    sta objpos+2
pbullstor 
    sta objpos+3
    rts
    
; An enemy was killed by the player 
; bullet, so morph the bullet into a 
; light red explosion.  

killbull 
    lda explodedelay
    cmp #2
    beq explodeon
    inc explodedelay 
    rts 
    
; Ready to animate explosion    

explodeon 
    lda #0
    sta explodedelay
    ldx explodepointer
    lda explframe,x 
    sta $07f9
    lda #$0a 
    sta $d028
    inx 
    cpx #6
    beq removebull
    inc explodepointer 
    rts
removebull
    ldx #0
    stx explodepointer
    lda #0
    sta pbullpos
    sta bulldead
    rts
        
;--------------------------------------
;Enemy control
;--------------------------------------
enemyctrl

; Setup the enemy frame type and colour
; according to the selection table 
; launched to all enemies.

e1tsm lda enemy1type
    sta $07fa 
e2tsm lda enemy1type 
    sta $07fb
e3tsm lda enemy1type 
    sta $07fc 
e4tsm lda enemy1type
    sta $07fd
e5tsm lda enemy1type 
    sta $07fe
e1csm lda #5  
    sta $d029
e2csm lda #5
    sta $d02a 
e3csm lda #5
    sta $d02b 
e4csm lda #5
    sta $d02c
e5csm lda #5
    sta $d02d 

; Now move those enemies accordingly

    jsr moveenemies
    rts
    
;Move enemies (inside a loop) 

moveenemies 
    ldx #$00
testmove    
    jsr moveenemyx
    jsr moveenemyy
    inx
    inx 
    cpx #$0a 
    bne testmove 
    rts 
    
;Test enemy X direction,0=left/1=right

moveenemyx 
    lda enemydir,x 
    cmp #1
    bne movel
    jmp mover
    
; Move selected enemies left until 
; they have reached the edge of the 
; screen.

movel   
    lda enemypos,x
    sec
    sbc enemyspeed,x
    cmp #lstop ;Min left pos 
    bcs storel
    ;Reverse direction 
    lda #1
    sta enemydir,x 
    rts
storel  sta enemypos,x 
    rts 
    
; Move selected enemies right until 
; they have reached the edge of the 
; screen. 

mover lda enemypos,x 
    clc 
    adc enemyspeed,x
    cmp #rstop ;Max right pos
    bcc storer
    ;Reverse direction 
    lda #0
    sta enemydir,x 
    rts
storer  sta enemypos,x 
    rts 
    
; Test enemy Y movement direction 
; 0 = up, 1 = down 

moveenemyy
    
    lda enemydir+1,x 
    cmp #1
    beq moved
    
;Move enemies upwards.

    lda enemypos+1,x 
    sec 
    sbc enemyspeed+1,x
    cmp #ustop
    bcs storeu 
    lda #1
    sta enemydir+1,x 
    rts 
storeu  sta enemypos+1,x 
    rts 
    
;Move enemies downwards 

moved lda enemypos+1,x 
    clc 
    adc enemyspeed+1,x
    cmp #dstop
    bcc stord
    lda #0
    sta enemydir+1,x
    rts 
stord   sta enemypos+1,x 
    rts

;--------------------------------------
; Enemy bullet control
;--------------------------------------
ebcontrol 
    jsr randomtable
    lda ebullpos
    beq selectshot
    lda #$aa
    sta $07ff 
    lda #$0d
    sta $d02e
    lda ebullpos+1
    clc
    adc #4
    cmp #$ca 
    bcc storebul
    lda #$00
    sta ebullpos    
    rts

storebul
    sta ebullpos+1
    rts

; Select next enemy to shoot. First 
; check the counter before firing the 
; next bullet.
    
selectshot
    lda bullwaittime 
    cmp fireduration
    beq nowait
        inc bullwaittime
    rts
nowait 
    lda #0
    sta bullwaittime  
    
; Select the enemy to drop a bomb

selectnextshot
    lda ranbull
    cmp #0
    beq enemy1fire
    cmp #1
    beq enemy2fire
    cmp #2
    beq enemy3fire
    cmp #3
    beq enemy4fire
    cmp #4
    beq enemy5fire
    jmp enemy1fire
    
; Enemy 1 firing

enemy1fire
    ldx enemypos
        beq e1nofire
    ldy enemypos+1
    stx ebullpos
    sty ebullpos+1
    jsr playebullfire
    jmp resetdur 
e1nofire 
        jmp setdur
        
; Enemy 2 firing    

enemy2fire
    ldx enemypos+2
        beq e2nofire
    ldy enemypos+3
    stx ebullpos
    sty ebullpos+1
    jsr playebullfire
    jmp resetdur
e2nofire 
        jmp setdur
        
    
; Enemy 3 firing 

enemy3fire
    ldx enemypos+4
        beq e3nofire
    ldy enemypos+5
    stx ebullpos
    sty ebullpos+1
    jsr playebullfire
    jmp resetdur
e3nofire
        jmp setdur
        
; Enemy 4 firing 

enemy4fire
    ldx enemypos+6
        beq e4nofire
    ldy enemypos+7
    stx ebullpos
    sty ebullpos+1
    jsr playebullfire
    jmp resetdur
e4nofire 
        jmp setdur

; Enemy 5 firing 

enemy5fire
    ldx enemypos+8
        beq e5nofire
    ldy enemypos+9
    stx ebullpos 
    sty ebullpos+1
    jsr playebullfire
    jmp resetdur
e5nofire 

; Selected enemy not available to 
; shoot so set the enemy fire duration
; to its expiry duration time.
        
setdur
        lda fireduration
        sta bullwaittime
        rts
        
; An enemy has been selected and has
; fired a bullet succeessfully. Reset
; the bullet wait time before the next
; enemy can fire it.        
        
resetdur 
        lda #0
        sta bullwaittime
        rts
        
; Play enemy bullet firing sfx

playebullfire   
    lda ebullpos
    beq nosfxfire
    lda #sfxefire 
    jsr sfxinit
nosfxfire    
    rts
          
;Rotate the table of bytes to select
;which enemy should be the next to 
;fire.    

randomtable   
   
    ldx firepointer
    lda rantable,x 
    sta ranbull
    inx 
    cpx #45 ;45 bytes table
    beq looptbl
        inc firepointer
        rts
looptbl
    ldx #0
        stx firepointer
    rts
;--------------------------------------
; Collision detection
;--------------------------------------
  
coldetect

;Calculate collision coords

    jsr calccol

; Test player bullet to enemy collision

    jsr bull2enemy

; Test player to enemy/enemy bullet 

    jsr plr2enemy

    rts 
    
;Calculate collision co-ordinates 
calccol 

; Calculate player bullet collision 
; range.

    lda pbullpos
    sec
    sbc #boxl
    sta collision1
    clc 
    adc #boxr
    sta collision1+1
    lda pbullpos+1
    sec
    sbc #boxd
    sta collision1+2
    clc 
    adc #boxu 
    sta collision1+3    

; Calculate player ship collision
; range.    

    lda shippos
    sec 
    sbc #boxl 
    sta collision2
    clc 
    adc #boxr 
    sta collision2+1
    lda shippos+1
    sec 
    sbc #boxd 
    sta collision2+2
    clc 
    adc #boxu 
    sta collision2+3
    rts 
    
; Test enemy to player bullet 
; collision 

bull2enemy 

; Check if player bullet is already 
; dead. If not, jump to process 
; collision check routine, else exit 
; from subroutine

    lda bulldead
    beq processc
    rts   

; Process collision test

processc    
    ldx #$00
tbcoll  lda enemypos,x
    cmp collision1
    bcc notshot
    cmp collision1+1
    bcs notshot 
    lda enemypos+1,x
    cmp collision1+2
    bcc notshot 
    cmp collision1+3
    bcs notshot 

; This is done for each enemy shot

    dec hitpoints,x
    dec hitpoints+1,x
    lda hitpoints,x
    cmp #0 ;No lives left
    beq killenemy
    
; The enemy is hit, but is not yet
; dead. Instead of kill the player 
; bullet, move it off the screen.

    lda #0
    sta pbullpos 
    
    ;Add 100 points
    jsr scorepoints
    rts
    
killenemy    

; The enemy is killed.  
; Remove enemy shot and disable
; movement

    lda #0
    sta enemypos,x 
    sta enemypos+1,x 
    sta enemyspeed,x 
    sta enemyspeed+1,x 
    
; also reset explosion values 

    lda #0
    sta explodedelay
    sta explodepointer
    
; finally declare player bullet as 
; destroyed     

    lda #1
    sta bulldead
    
; Play enemy death sfx 

    lda #sfxedead 
    jsr sfxinit

; Subtract the amount of aliens to 
   ;kill.

   jsr subalien

; Award 300 points per kill
   jsr scorepoints
   jsr scorepoints
   jsr scorepoints
   rts      

; No enemies are killed, so check the 
; next enemy.

notshot inx 
    inx 
    cpx #$0a
    bne tbcoll
    rts 
    
; Score points based on alien killed 
; and subtract the number of aliens 
; to be destroyed before moving onto 
; the next level. 

scorepoints       
    jsr add100
    jsr updatepanel
    rts
    
;Add 100 points per alien shot 
;according to the status panel 

add100
    inc score+3
    ldx #$04
addpts  lda score,x 
    cmp #$3a
    bne scok
    lda #$30
    sta score,x 
    inc score-1,x 
scok  dex 
    bne addpts 
        
;Now do the same for the virtual 
;score. This is because we want to 
;add extra lives for every 10,000 
;points scored during gameplay.

        inc vscore+3
        ldx #$04
addpts2 
        lda vscore,x 
        cmp #$3a
        bne vscok
        lda #$30
        sta vscore,x 
        inc vscore-1,x 
vscok 
        dex 
        bne addpts2
        
; Check if the second digit in the 
; score results as a '1'. If so, award 
; an extra life to the player. 
        
        lda vscore+1
        cmp #$31 ;1 detected, as 1,0000
        beq addlife
        rts 
        
; Award an extra life to the player 

addlife
        inc lives
        lda lives
        cmp #$3a
        bne xlivesok 

; An illegal value to lives, detected
; set max lives as 9

        lda #$39
        sta lives
        
; Play spawn SFX to once again 

xlivesok
        lda #sfxextralife
        jsr sfxinit

; Reset the virtual score to 000000

        ldx #$00
resetvscore
        lda #$30
        sta vscore,x 
        inx 
        cpx #6
        bne resetvscore
        rts

; Also give the player a shield as 
; an extra reward.

        lda #200
        sta shieldtimer 
        ldx #0
        stx shieldptr

;Deduct amount of aliens to be shot 
;then update the panel 

subalien
    dec aliensleft+2
    ldx #$02
subloop
    lda aliensleft,x 
    cmp #$2f
    bne subok
    lda #$39
    sta aliensleft,x
    dec aliensleft-1,x 
subok dex 
    bne subloop
    lda aliensleft
    cmp #$30
    beq chkdig2
    rts 
chkdig2 lda aliensleft+1
    cmp #$30
    beq chkdig3 
    rts 
chkdig3 lda aliensleft+2
    cmp #$30
    beq levelclear
    rts 
    
; Level completed, clear all sprites
; off screen and display LEVEL clear
; in the middle of the screen

levelclear    
   
; Award 1000 points based on the amount
; of lives that the player has also.
; Convert lives into the lives count 
; +1 value into the bonus pointer

        lda lives
        sec 
        sbc #$30
        sta bonusptr

; Now subtract 1 to the bonus pointer 
; for more accuracy.

        dec bonusptr 

; Now call the add bonus routine the 
; based on the actual amount of lives 
; the play has.        

        ldy bonusptr 
addbonus
        jsr add1000s
        dey
        bpl addbonus
        jmp bonusdone

; Add bonus points to score and virtual
; score.         

add1000s        
        inc score+2
        ldx #3
add1000
        lda score,x 
        cmp #$3a
        bne bonusok1
        lda #$30
        sta score,x
        inc score-1,x 
bonusok1
        dex
        bne add1000
        inc vscore+2
        ldx #3
add1000b
        lda vscore,x 
        cmp #$3a 
        bne bonusok2 
        lda #$30
        sta vscore,x 
        inc vscore-1,x 
bonusok2 
        dex
        bne add1000b 

; Check if second digit in virtual 
; score = 1. If so, give extra lives 

        lda vscore+1
        cmp #$31
        beq awardxlife2
        jmp noxlife2
        
awardxlife2 
        inc lives 
        lda lives 
        cmp #$3a
        beq errorlives2
        
; Reset virtual score again

        ldx #$00
resetvscore2        
        lda #$30
        sta vscore,x 
        inx 
        cpx #6
        bne resetvscore2
        jmp noxlife2
        
; Set lives counter as 9 max

errorlives2         
        lda #$39
        sta lives
        
; Play level complete sfx 

noxlife2
        rts 
        
bonusdone        
    lda #sfxlclear
    jsr sfxinit
    
nextlevel    
    lda #0
    sta bgflashdelay
    sta bgflashpointer
    
; Clear out all sprites 

    ldx #0
removesprs
    lda #0
    sta $d000,x 
    sta $d001,x 
    sta objpos,x 
    inx 
    cpx #$10
    bne removesprs 
    
; Clear out the quota as 000

    ldx #$00
clearq  
        lda #$30
    sta alienstxt,x 
    inx 
    cpx #3
    bne clearq

;Backup the screen characters which 
;make the space background. 

    ldx #$00
backupstars
    lda $05c7,x 
    sta starbackup,x ;Spare memory 
        
; also add the level complete message

    lda lcmsg,x 
    sec
    sbc #eorcode
        sta $05c7,x 
    lda #5 ;Set text as green
    sta $d9c7,x
    inx 
    cpx #11
    bne backupstars
        jsr updatepanel

; Lock fire depress, in order to wait
; for fire to be released after 
; pressing the button.

    lda #0 
    sta firebutton
    
;Now create a loop that will f
;animate the stars   

lcloop  
        jsr synctimer
    jsr starfield
        jsr flashcounter
    lda $dc00
    lsr 
    lsr
    lsr 
    lsr
    lsr 
    bit firebutton
    ror firebutton
    bmi lcloop
    bvc lcloop
    
    lda #0
    sta firebutton   

; Restore the starfield that was 
; backed up 

    ldx #$00
restorestars 
    lda starbackup,x 
    sta $05c7,x 
    lda #$06
    sta $d9c7,x
    inx 
    cpx #11
    bne restorestars

; Go onto the next level, but if level
; is past level 8, then the game has  
; been completed.

    inc levelpointer
    lda levelpointer
    cmp #8 ;Exceeds level 8
    beq gamecomplete
    
        ; Restore shield on next level

        lda #200
        sta shieldtimer 
        ldx #0
        stx shieldptr

    jmp buildlevel
;--------------------------------------
;The game has been completed, display
;the end screen.

gamecomplete

; Play game complete sound effects 

    lda #sfxgfinish
    jsr sfxinit
    
; Display the message congratulating 
; the player on completing the game 

    ldx #$00
setmsg1 lda wdmsg,x 
    sec 
    sbc #eorcode
    sta $0550,x
    lda #5
    sta $d950,x
    inx 
    cpx #9
    bne setmsg1
    
    ldx #$00
setmsg2 lda edmsg,x
    sec 
    sbc #eorcode
    sta $05bc,x
    lda #7
    sta $d9bc,x 
    inx 
    cpx #32
    bne setmsg2 
    
    ldx #$00
setmsg3 lda edmsg2,x 
    sec 
    sbc #eorcode
    sta $063a,x 
    lda #1
    sta $da3a,x
    inx 
    cpx #21
    bne setmsg3
    
    ldx #$00
setmsg4 lda edmsg3,x 
    sec 
    sbc #eorcode 
    sta $068f,x
    lda #2
    sta $da8f,x
    inx 
    cpx #12
    bne setmsg4
    
    lda #0
    sta firebutton
  
; Check for new hi score 

    jsr checkhi
  
; Run the endloop and then wait  
; Wait for fire to be pressed 
; to exit the game back to the
; title screen.

endloop jsr synctimer
    jsr starfield
        jsr flashcounter
        
    lda $dc00 
    lsr 
    lsr 
    lsr 
    lsr 
    lsr 
    bit firebutton
    ror firebutton
    bmi endloop
    bvc endloop

    ;Go back to the title screen
    jmp titlecode
    
;--------------------------------------
  
; Test enemy and enemy bullet to player
; collision 
;--------------------------------------

plr2enemy
        lda shieldtimer
        bne skipepcol
    lda playerdead
    beq processc2
skipepcol        
    rts 
    
; Process enemy / player collision 
; checks. 

processc2   
    ldx #$00
plcoll  lda enemypos,x 
    cmp collision2 
    bcc plralive
    cmp collision2+1
    bcs plralive 
    lda enemypos+1,x 
    cmp collision2+2
    bcc plralive 
    cmp collision2+3
    bcs plralive 
        
; Player is hit, kill it  

    lda #0
    sta deathdelay
    sta deathpointer
    lda #1
    sta playerdead
    lda #sfxpdead
    jsr sfxinit
    rts

; No collision, check for the next 
; Alien
        
plralive
    inx 
    inx 
    cpx #$0c
    bne plcoll
    rts
            
;--------------------------------------
; Check all enemies are dead. If they
; are, move onto the next level.
; Basically all enemies placed at $00
; X position are out.
;--------------------------------------

checkalldead 
    ldx #$00
chkzero lda enemypos,x 
    bne notdead
    inx 
    inx
    cpx #$0a
    bne chkzero

; All enemies are killed, so move on 
; to the next level.    

    lda bulldead
    beq wavedone
    rts 
    
wavedone  
    jmp levelstart
    
; Not all enemies are killed    

notdead   
    rts 
    
;--------------------------------------
;Update the scoring status panel, 
;amount of aliens to kill onto the 
;screen RAM
;--------------------------------------

updatepanel 

; Copy scores and hi score first 

    ldx #$00
copyscores
    lda score,x 
    sta scoretxt,x 
    lda hiscore,x 
    sta hitxt,x
    
; Paint those digits in score and 
; hi score yellow.

    lda #7
    sta scorecol,x
    sta hicol,x
    inx 
    cpx #6
    bne copyscores 
    
; Copy level number to screen   

    lda level
    sta leveltxt
    
; Copy lives to screen

    lda lives 
    sta livestxt
  
; Copy level number to screen 

    lda level
    sta leveltxt

; Paint those single digits yellow   

    lda #7
    sta livescol
    sta levelcol 
    
; Finally copy amount of aliens to 
; shoot on screen 

    ldx #$00
copyalientxt    
    lda aliensleft,x
    sta alienstxt,x
    lda #$05
    sta alienscol,x 
    inx 
    cpx #$03
    bne copyalientxt
    rts   
;--------------------------------------
;Hi score check routine 
;--------------------------------------
checkhi

; Check current score and see if it 
; becomes the new hi score 

     lda score
     sec
     lda hiscore+5
     sbc score+5
     lda hiscore+4
     sbc score+4
     lda hiscore+3
     sbc score+3
     lda hiscore+2
     sbc score+2
     lda hiscore+1
     sbc score+1
     lda hiscore
     sbc score 
     bpl nohiscore
     
; Copy player score as new hi score 

    ldx #$00
copyhi  lda score,x 
    sta hiscore,x 
    inx 
    cpx #6
    bne copyhi 
nohiscore
    jsr updatepanel
    rts

;--------------------------------------
; Flash game counter 
;--------------------------------------

flashcounter
        lda ctflashdelay
        cmp #3
        beq ctflashok 
        inc ctflashdelay 
        rts 
ctflashok 
        lda #0
        sta ctflashdelay
        
        ldx ctflashpointer
        lda ctflashtbl,x 
        sta $d813
        sta $d814
        sta $d815
        lda ctflashtbl+1,x 
        sta $d811 
        sta $d817
        lda ctflashtbl+2,x 
        sta $d810
        sta $d818
        lda ctflashtbl+3,x 
        sta $d80f
        sta $d819
        inx 
        cpx #$08
        beq loopctflash
        inc ctflashpointer 
        rts 
loopctflash
        ldx #0
        stx ctflashpointer
        rts        

;--------------------------------------
;In game pointers and tables
;--------------------------------------
   
   
;Raster sync timer 
rt .byte 0  
;System PAL/NTSC check pointer
system .byte 0
;NTSC timer pointer for delaying sound
ntsctimer .byte 0
;Player shield counter 
shieldtimer .byte 0
;Shield colour pointer
shieldptr .byte 0
;Bonus pointer 
bonusptr .byte 0

ptrstart
;Level pointer
levelpointer 
        .byte 0
;Game screen flash pointer
bgflashpointer 
        .byte 0
;Counter flash pointer 
ctflashdelay
        .byte 0
ctflashpointer 
        .byte 0

;Enemy / spawn selection pointer
selectptr .byte 0
selectptr2 .byte 0
spawnposptr .byte 0,0
;Enemy firing duration (intensity)
fireduration .byte 0
;Enemy fire pointer
firepointer .byte 0
ranbull .byte 0
;Player fire button press pointer
firebutton .byte 0

;Starfield temporary bytes  

ftemp1 .byte 0
ftemp2 .byte 0
ftemp3 .byte 0

;Starfield delay pointers
fielddelay1 .byte 0
fielddelay2 .byte 0
fielddelay3 .byte 0

;Object pointers 
bulldead .byte 0
playerdead .byte 0
deathdelay  .byte 0
deathpointer .byte 0
explodedelay   .byte 0
explodepointer .byte 0
rantemp .byte 0
bullwaittime .byte 0
selectionptr .byte 0
bgflashdelay .byte 0
;Animation speed (all sprites)
animspeed .byte 0 
;Animation speed2 (death)
animspeed2 .byte 0
;Animation pointer (player)
animptr .byte 0
;Animation pointer (enemy)
animptr2 .byte 0
;Animation pointer (death)
animptr3 .byte 0
ptrend

;Player object type
plrtype .byte $80 
;Player bullet type
bulltype .byte $83
;Enemy type data 
enemytype
enemy1type .byte $8a
enemy2type .byte $8a
enemy3type .byte $8a
enemy4type .byte $8a
enemy5type .byte $8a
enemy6type .byte $8a
enemy7type .byte $8a
enemy8type .byte $8a


;Game starting position

startpos 
  .byte $56,$ca ;Player x/y
  .byte $00,$00 ;Bullet x/y
spawnpos  ;Enemy spawn start
  .byte $90,$60 ;Enemy 1 x/y
  .byte $70,$70 ;Enemy 2 x/y
  .byte $80,$80 ;Enemy 3 x/y
  .byte $50,$90 ;Enemy 4 x/y 
  .byte $20,$a0 ;Enemy 5 x/y
  .byte $f0,$00 ;Enemy bullet

;Game sprite colour data 
sprcolour
  .byte $03,$07,$05,$05
  .byte $05,$05,$05,$0d
  
;Object type table on startup 

typetbl
  .byte $80,$83,$8a,$8a
  .byte $8a,$8a,$8a,$8e
  
;Player shield colour table 
shieldcol
  .byte $0e,$03,$0d,$01
  .byte $0d,$03,$0e,$04
  
;Setup starting enemy speed 
  
startspeed 
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  
;Object pointers and properties

 ;Sprite object positions 
 ;(self-modifying)
 
objpos 
shippos
  .byte $00,$00 ;Player ship
pbullpos  
  .byte $00,$00 ;Player bullet
enemypos  
  .byte $00,$00 ;Alien 1
  .byte $00,$00 ;Alien 2
  .byte $00,$00 ;Alien 3
  .byte $00,$00 ;Alien 4
  .byte $00,$00 ;Alien 5
ebullpos  
  .byte $00,$00 ;Alien bullet
  
;Collision co-ordinates 
collision1

;Enemy to player bullet 
  .byte $00,$00,$00,$00
  
collision2
;Enemy / enemy bullet to player
  .byte $00,$00,$00,$00
  
 ;Enemy directional pointers (x/y)

enemydir
  .byte $00,$00 
  .byte $00,$01
  .byte $01,$00
  .byte $01,$01
  .byte $00,$01
    
enemyspeed
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  .byte $01,$02
  
 ;Enemy hits to kill  
hitpoints
  .byte $01,$01
  .byte $01,$01
  .byte $01,$01
  .byte $01,$01
  .byte $01,$01
  .byte $01,$01
        
;Sprite frame tables 

 ;Player sprite animation table
playerframe
    .byte $80,$81,$82,$81
    
 ;Player bullet 
pbullframe
    .byte $83
    
 ;Explosion frame 
explframe
    .byte $84,$85,$86,$87
    .byte $88,$89
explend   
    
 ;Enemy object animation tables. 
 ;There are eight different enemy 
 ;groups in which the player must 
 ;fight against.

enemyframe1 ;Alien type 1
    .byte $8a,$8b,$8c,$8d
enemyframe2 ;Alien type 2
    .byte $8e,$8f,$90,$91
enemyframe3 ;Alien type 3
    .byte $92,$93,$94,$95
enemyframe4 ;Aline type 4
    .byte $96,$97,$98,$99
enemyframe5 ;Alien type 5
    .byte $9a,$9b,$9c,$9d
enemyframe6 ;Alien type 6
    .byte $9e,$9f,$a0,$a1
enemyframe7 ;Alien type 7
    .byte $a2,$a3,$a4,$a5
enemyframe8 ;Alien type 8
    .byte $a6,$a7,$a8,$a9
    
; Enemy morphing frame (also 4 frames)

morphframe
    .byte $ab,$ac,$ad,$ae
    
;Status pointers for scoring, lives,
;level, hi score, and amount of aliens
;to be destroyed before moving onto 
;the next level. 

; Score table

score   .byte $30,$30,$30
                .byte $30,$30,$30
                
; Virtual score (for calculating 
; extra lives at every 10,000 points 
; scored.        

vscore        .byte $30,$30,$30
                .byte $30,$30,$30
    
; Lives counter   

lives .byte $33   

; Level counter (wave)

level   .byte $31

; Hi score table 

hiscore .byte $30,$30,$30
    .byte $30,$30,$30
    
;Aliens kill count status

aliensleft
    .byte $30,$30,$30
      
;Game over and well done text 

gomsg  .text "game@over"
lcmsg   .text "level@clear"
wdmsg   .text "well@done" 
edmsg   .text "you@have "
        .text "defeated@all@"
    .text "the@aliens"
edmsg2  .text "thank@you@for@playing"
edmsg3  .text "galaxo@blast"            

;Level flash table 

bgflashtbl
    .byte $06,$02,$04,$0a
    .byte $07,$01,$07,$0a
    .byte $04,$02,$06,$00


;Level spawn tables are setup, make 
;small tables to indicate enemy type,
;colour, speed.

;Low byte addresses of where each 
;level spawn table is based 

spawntblo
     .byte <l1spawntbl
     .byte <l2spawntbl
     .byte <l3spawntbl
     .byte <l4spawntbl
     .byte <l5spawntbl
     .byte <l6spawntbl
     .byte <l7spawntbl
     .byte <l8spawntbl

;Hi byte addresses of where each 
;level spawn table is based.
     
spawntbhi
    .byte >l1spawntbl
    .byte >l2spawntbl
    .byte >l3spawntbl
    .byte >l4spawntbl
    .byte >l5spawntbl
    .byte >l6spawntbl
    .byte >l7spawntbl
    .byte >l8spawntbl
    
;Object spawn position table lo/hi 
;byte values 
spawnposlo
        .byte <spawnptbl1
        .byte <spawnptbl2
        .byte <spawnptbl3
        .byte <spawnptbl4
        .byte <spawnptbl5
        
spawnposhi
        .byte >spawnptbl1
        .byte >spawnptbl2
        .byte >spawnptbl3
        .byte >spawnptbl4
        .byte >spawnptbl5
        
;Low byte of the enemy sprite frame 
;to call based on enemy type    

etypelo  
         .byte <enemy1type
     .byte <enemy2type
     .byte <enemy3type
     .byte <enemy4type
     .byte <enemy5type
     .byte <enemy6type
     .byte <enemy7type
     .byte <enemy8type
     
;Hi byte of the enemy sprite frame 
;to call based on enemy type     
     
etypehi  
         
         .byte >enemy1type
     .byte >enemy2type
     .byte >enemy3type
     .byte >enemy4type
     .byte >enemy5type
     .byte >enemy6type
     .byte >enemy7type
     .byte >enemy8type  
     

;Random table to select enemy to drop 
;bombs 

rantable    
    .byte 0,4,2,1,3
    .byte 4,2,3,1,0
    .byte 2,0,1,4,3
    .byte 0,1,3,2,0
    .byte 0,4,2,4,3
    .byte 0,2,3,1,0
    .byte 3,1,4,0,2
    .byte 2,0,4,3,1
    .byte 1,3,5,1,3
rantablend    

;Spawn sequence table 

spawnseqtbl
        .byte 0,3,2,1,4
        .byte 2,4,3,1,2
        .byte 0,3,1,2,4
        .byte 3,2,4,1,0
        .byte 4,1,3,2,1
        .byte 3,4,1,2,4
        .byte 0,3,1,2,4
        .byte 1,2,4,3,0
        .byte 3,1,0,4,2
        .byte 0,1,2,3,4

;Table 1 - Pattern: Chevron up

spawnptbl1
        .byte $56,$56
    .byte $3e,$6e
    .byte $6e,$6e
    .byte $26,$86
    .byte $86,$86
        
;Table 2 - Pattern: Diagonal Cross 

spawnptbl2
        .byte $0e,$3e
    .byte $9e,$3e
    .byte $56,$7e
    .byte $0e,$b6
    .byte $9e,$b6

;Table 3 - Horiz/vertical cross 

spawnptbl3
        .byte $56,$56
    .byte $26,$7e
    .byte $56,$7e
    .byte $85,$7e
    .byte $56,$a6

;Table 4 - Chevron down 

spawnptbl4
        .byte $26,$56
    .byte $86,$56
    .byte $3e,$7e
    .byte $6e,$7e
    .byte $56,$a6

;Table 5 - scattered around

spawnptbl5
        .byte $0e,$56
    .byte $56,$6e
    .byte $7e,$3e
    .byte $3e,$9e
    .byte $9e,$6e

;random table to select enemy type to 
;spawn

;0 = alien type 1 -1 hit
;1 = alien type 2 -2 hits
;2 = alien type 3 -3 hits
;4 = alien type 4 -1 hit fast 
;5 = alien type 5 -2 hit fast
;6 = alien type 6 -3 hits fast
;7 = alien type 7 -2 hits faster
;8 = alien type 8 -3 hits faster

spawntbl 
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     

l1spawntbl
     .byte 0,0,1,0,0
     .byte 0,1,0,1,0
     .byte 1,0,0,0,1
     .byte 0,1,0,1,0
     .byte 1,0,1,0,1
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     .byte 0,0,0,0,0
     
l2spawntbl
     .byte 0,0,1,0,1
     .byte 2,0,1,0,0
     .byte 0,1,0,0,2
     .byte 0,1,0,1,0
     .byte 0,1,0,2,0
     .byte 0,2,0,1,0
     .byte 0,1,0,1,0
     .byte 2,0,1,0,0
     .byte 0,2,0,1,0
     
l3spawntbl
     .byte 0,2,0,2,1
     .byte 0,2,1,2,1
     .byte 1,1,2,2,0
     .byte 0,1,0,1,0
     .byte 0,2,2,1,0
     .byte 1,0,2,1,2
     .byte 2,1,2,1,0
     .byte 0,1,1,0,2
     .byte 0,2,0,1,1
     
l4spawntbl
     .byte 1,1,3,0,1
     .byte 1,2,1,1,3
     .byte 0,1,3,1,2
     .byte 2,1,0,1,0
     .byte 0,1,2,1,1
     .byte 2,1,3,1,0
     .byte 0,2,0,1,1
     .byte 1,1,1,0,2
     .byte 0,1,1,1,2
     
l5spawntbl 
     .byte 1,1,2,1,2
     .byte 1,2,1,1,2
     .byte 1,1,3,1,2
     .byte 2,1,4,3,1
     .byte 1,2,0,3,0
     .byte 2,1,4,1,3
     .byte 1,1,2,3,0
     .byte 2,2,1,3,0
     .byte 0,3,0,1,0
     
l6spawntbl
     .byte 2,3,2,2,4
     .byte 2,3,3,1,2
     .byte 4,2,2,2,1
     .byte 2,2,3,3,2
     .byte 1,1,4,2,3
     .byte 4,2,3,1,2
     .byte 4,2,3,1,4
     .byte 2,3,1,4,3
     .byte 3,1,2,4,3
     
l7spawntbl 
     .byte 4,3,0,3,4
     .byte 4,0,6,0,5
     .byte 0,4,3,4,6
     .byte 4,4,4,5,3
     .byte 4,2,6,3,1
     .byte 2,4,1,4,2
     .byte 6,5,1,4,0
     .byte 2,0,3,0,4
     .byte 3,5,0,2,5
     
l8spawntbl
     .byte 7,2,6,2,7
     .byte 3,6,4,6,3
     .byte 6,7,2,7,6
     .byte 4,2,6,2,4
     .byte 3,6,7,6,3
     .byte 6,1,3,1,6
     .byte 2,6,7,6,2
     .byte 6,1,2,1,6
     .byte 7,3,6,3,7
     
;Colour according to enemy type.
;Each enemy has a set colour
     
ecolour  
        .byte $05,$0a,$0f,$0e
        .byte $03,$08,$07,$04
     
;Enemy X speed table according to the 
;enemy type (Speed set in units of 1)
;as thee sprite X position has been
;doubled.    

espeedx  
        .byte $01,$01,$01,$02
    .byte $02,$02,$03,$03

;Enemy Y speed table according to the
;enemy type (Speed set in units of 2)

espeedy  
         .byte $02,$02,$02,$02
     .byte $02,$02,$06,$06
     
;Enemy firing duration (according to
;level - this triggers firing intensity
;to the game.

firetbl        
        .byte 120,110
        .byte 100,90
        .byte 80,70
        .byte 60,50
        .byte 40,30
        .byte 20,10
         
;Number of hits to destroy an enemy
;according to enemy type.
     
ehits
     .byte $01,$02,$03,$01
     .byte $02,$03,$02,$03
     
         
; Amount of enemies to be killed 
; according to the digits set on the 
; shot counter. (HTU)

digitset1 ;Hundreds
     .byte $30,$30,$30,$30
     .byte $30,$30,$30,$31
digitset2 ;Tens
     .byte $32,$33,$33,$34
     .byte $34,$35,$35,$30
digitset3 ;Units
     .byte $35,$30,$35,$30
     .byte $35,$30,$35,$30
     
; Level digits 
levelnos 
         .byte $31,$32,$33,$34
     .byte $35,$36,$37,$38

; Starfield colour table      
starcols .byte $06,$02,$04,$07
         .byte $01,$07,$04,$02
                 
 
;Counter flash colour table 
ctflashtbl
  .byte $06,$05,$03,$01
  .byte $07,$04,$02,$06
  .byte $06,$05,$03         
;====================================== 